1   /*
2    * Copyright (C) 2008 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
20  
21  import com.google.common.annotations.GwtCompatible;
22  
23  import javax.annotation.Nullable;
24  
25  /**
26   * Implementation of {@link ImmutableMap} with exactly one entry.
27   *
28   * @author Jesse Wilson
29   * @author Kevin Bourrillion
30   */
31  @GwtCompatible(serializable = true, emulated = true)
32  @SuppressWarnings("serial") // uses writeReplace(), not default serialization
33  final class SingletonImmutableBiMap<K, V> extends ImmutableBiMap<K, V> {
34  
35    final transient K singleKey;
36    final transient V singleValue;
37  
38    SingletonImmutableBiMap(K singleKey, V singleValue) {
39      checkEntryNotNull(singleKey, singleValue);
40      this.singleKey = singleKey;
41      this.singleValue = singleValue;
42    }
43  
44    private SingletonImmutableBiMap(K singleKey, V singleValue,
45        ImmutableBiMap<V, K> inverse) {
46      this.singleKey = singleKey;
47      this.singleValue = singleValue;
48      this.inverse = inverse;
49    }
50  
51    SingletonImmutableBiMap(Entry<? extends K, ? extends V> entry) {
52      this(entry.getKey(), entry.getValue());
53    }
54  
55    @Override public V get(@Nullable Object key) {
56      return singleKey.equals(key) ? singleValue : null;
57    }
58  
59    @Override
60    public int size() {
61      return 1;
62    }
63  
64    @Override public boolean containsKey(@Nullable Object key) {
65      return singleKey.equals(key);
66    }
67  
68    @Override public boolean containsValue(@Nullable Object value) {
69      return singleValue.equals(value);
70    }
71  
72    @Override boolean isPartialView() {
73      return false;
74    }
75  
76    @Override
77    ImmutableSet<Entry<K, V>> createEntrySet() {
78      return ImmutableSet.of(Maps.immutableEntry(singleKey, singleValue));
79    }
80  
81    @Override
82    ImmutableSet<K> createKeySet() {
83      return ImmutableSet.of(singleKey);
84    }
85  
86    transient ImmutableBiMap<V, K> inverse;
87  
88    @Override
89    public ImmutableBiMap<V, K> inverse() {
90      // racy single-check idiom
91      ImmutableBiMap<V, K> result = inverse;
92      if (result == null) {
93        return inverse = new SingletonImmutableBiMap<V, K>(
94            singleValue, singleKey, this);
95      } else {
96        return result;
97      }
98    }
99  }